package com.fxd.cglib;

import com.fxd.proxy2.Iproducer;
import com.fxd.proxy2.producer;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @auther fuxudong
 * @date 2021/1/25 - 13:01
 * 模拟一个消费者
 */
public class client {
    public static void main(String[] args) {

        final producer producer = new producer();
        /**
         * 动态代理：
         *      特点:字节码随用随创建，随用随加载
         *      作用：不修改源码的基础上对方法增强
         *      分类：
         *          基于接口的动态代理
         *          基于子类的动态代理
         *      基于子类的动态代理：
         *          涉及的类：enhancer
         *          提供者：第三方cglib库
         *      如何创建代理对象：
         *          使用enhancer类中的create方法
         *      创建代理对象的要求
         *          被代理类不能是最终类(被final修饰的类不能被继承)
         *      creat方法的参数：
         *          class:字节码
         *              它是用于指定被代理对象的字节码
         *          callback:用于提供增强的代码
         *          我们一般写的都是该接口的子接口实现类：
         *              MethodInsterceptor
         */
        producer cglibpro = (producer) Enhancer.create(producer.getClass(), new MethodInterceptor() {
            /**
             * 执行被代理对象的任何方法都会经过该方法
             * @param o
             * @param method
             * @param objects
             * 以上上参数和基于接口的动态代理invoke方法参数一样
             * @param methodProxy：当前执行方法的代理对象
             * @return
             * @throws Throwable
             */
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                //提供增强的代码
                Object result = null;
                //获取执行方法的参数
                Float money = (Float) objects[0];
                if ("saleProduct".equals(method.getName())) {
                    result = method.invoke(producer, money * 0.8f);
                }
                return result;
            }
        });
       cglibpro.saleProduct(12000f);

    }
}
